package net.qiujuer.sample.genius.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.AbsButton;
import ohos.agp.components.Image;
import ohos.agp.components.Text;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import net.qiujuer.genius.graphics.Blur;
import net.qiujuer.genius.ui.widget.CheckBox;
import net.qiujuer.sample.genius.ResourceTable;

import java.io.InputStream;

/**
 * BlurAbilitySlice
 *
 * @since 2021-05-10
 */
public class BlurAbilitySlice extends AbilitySlice {
    private static final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0x0021, "BlurAbilitySlice");
    private static final int SCALE_FACTOR = 6;
    private boolean mCompress;
    private Text mTime;

    private PixelMap mBitmap;
    private PixelMap mCompressBitmap;
    private Image mImageJava;
    private Image mImageJniPixels;
    private Image mImageJniBitmap;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        getWindow().setStatusBarColor(getColor(ResourceTable.Color_colorTitle));
        setUIContent(ResourceTable.Layout_ability_blur);
        initBlur();
    }

    private void initBlur() {
        // Find Bitmap
        mBitmap = getPixelMap(ResourceTable.Media_ic_blur);

        mImageJava = (Image) findComponentById(ResourceTable.Id_image_blur_java);
        mImageJniPixels = (Image) findComponentById(ResourceTable.Id_image_blur_jni_pixels);
        mImageJniBitmap = (Image) findComponentById(ResourceTable.Id_image_blur_jni_bitmap);
        mTime = (Text) findComponentById(ResourceTable.Id_text_blur_time);

        // Init src image
        ((Image) findComponentById(ResourceTable.Id_image_blur_self)).setPixelMap(mBitmap);

        // Compress and Save Bitmap
        int width = mBitmap.getImageInfo().size.width;
        int height = mBitmap.getImageInfo().size.height;
        PixelMap.InitializationOptions opt = new PixelMap.InitializationOptions();
        opt.editable = true;
        opt.pixelFormat = PixelFormat.RGB_565;
        mCompressBitmap = PixelMap.create(mBitmap, new Rect(0, 0, width, height), opt);

        // Set On OnCheckedChangeListener
        CheckBox checkBox = (CheckBox) findComponentById(ResourceTable.Id_checkbox_blur_isCompress);

        checkBox.addCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                mCompress = isChecked;
                applyBlur();
            }
        });

        findComponentById(ResourceTable.Id_iv_left).setClickedListener(comp -> terminate());

    }

    private void applyBlur() {
        // First clear
        clearDrawable();

        // Run Thread
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    final StringBuilder sb = new StringBuilder();
                    sb.append("Blur Time: ");
                    for (int i = 1; i < 4; i++) {
                        sb.append(blur(i)).append(" ");
                    }
                    getUITaskDispatcher().asyncDispatch(new Runnable() {
                        @Override
                        public void run() {
                            mTime.setText(sb.toString());
                        }
                    });
                } catch (Exception e) {
                    HiLog.debug(TAG, "");
                }
            }
        });
        thread.setDaemon(true);
        thread.start();
    }

    private long blur(int i) {
        long startMs = System.currentTimeMillis();
        try {
            // Is Compress
            float radius = 10;
            PixelMap overlay = getPixelMap(ResourceTable.Media_ic_blur);
            if (mCompress) {
                radius = 3;
                overlay = mCompressBitmap;
            }
            if (i == 1) {
                // Java
                overlay = Blur.onStackBlurJava(overlay, (int) radius);
            } else if (i == 2) {
                // Pixels JNI Native
                int w_ = overlay.getImageInfo().size.width;
                int h_ = overlay.getImageInfo().size.height;
                int[] pix = new int[w_ * h_];
                PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
                initializationOptions.size = new Size(w_, h_);
                overlay.readPixels(pix, 0, w_, new Rect(0, 0, w_, h_));

                // Jni Pixels Blur
                pix = Blur.onStackBlurPixels(pix, w_, h_, (int) radius);
                overlay = PixelMap.create(pix, initializationOptions);
            } else if (i == 3) {
                // Bitmap JNI Native
                overlay = Blur.onStackBlur(overlay, (int) radius);
            }
            // Show
            if (i == 1) {
                showDrawable(mImageJava, overlay);
            } else if (i == 2) {
                showDrawable(mImageJniPixels, overlay);
            } else if (i == 3) {
                showDrawable(mImageJniBitmap, overlay);
            }
        } catch (Exception ex) {
            HiLog.debug(TAG, "applyBluroverlay Exception " + ex.getMessage());
        }

        return System.currentTimeMillis() - startMs;
    }

    private void clearDrawable() {
        mImageJava.setPixelMap(null);
        mImageJniPixels.setPixelMap(null);
        mImageJniBitmap.setPixelMap(null);
    }

    private void refresh(int visible) {
        mImageJava.setVisibility(visible);
        mImageJniPixels.setVisibility(visible);
        mImageJniBitmap.setVisibility(visible);
    }

    private void showDrawable(final Image view, final PixelMap overlay) {
        getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                view.setPixelMap(overlay);
            }
        });
    }

    private PixelMap getPixelMap(int drawableId) {
        InputStream drawableInputStream = null;
        try {
            drawableInputStream = getContext().getResourceManager().getResource(drawableId);
            ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
            sourceOptions.formatHint = "image/png";

            ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
            decodingOptions.desiredPixelFormat = PixelFormat.ARGB_8888;
            ImageSource imageSource = ImageSource.create(drawableInputStream, sourceOptions);
            PixelMap pixelMap = imageSource.createPixelmap(decodingOptions);
            return pixelMap;
        } catch (Exception e) {
            HiLog.debug(TAG, e.toString());
        } finally {
            try {
                if (drawableInputStream != null) {
                    drawableInputStream.close();
                }
            } catch (Exception e) {
                HiLog.debug(TAG, e.toString());
            }
        }
        return null;
    }
}
